<?php

declare(strict_types=1);

namespace App\Controller;

use App\Component\UidBand;
use App\Model\MessageLog;
use App\Model\User;
use Hyperf\SocketIOServer\Annotation\Event;
use Hyperf\SocketIOServer\Annotation\SocketIONamespace;
use Hyperf\SocketIOServer\Socket;

/**
 * @SocketIONamespace("/")
 */
class WebSocketController extends AbstractWebSocketController
{

    /**
     * @Event ("login")
     * @param Socket $socket
     * @param $data
     * @return mixed
     */
    public function onLogin(Socket $socket, $data)
    {
        $identity = $data['identity'] ?? null;
        $user = User::query()->where('identity', $identity)->first();
        if (!$user) {
            $socket->emit('login', $this->closeMsg('用户不存在！'));
            return;
        }
        $user->status = 'online';
        $user->save();
        //判断用户是否已经登录
        $sid = UidBand::getInstance()->getFdByUid($user->id);
        if($sid){
            $socket->to($sid)->emit('login', $this->closeMsg('已在其他页面登录！'));
            //这里手动解绑再执行下面的绑定，防止并发
            UidBand::getInstance()->unBindUid($sid, $user->id);
        }
        UidBand::getInstance()->bindUid($socket->getSid(), $user->id);
        //加入群组
        $groups = $user->groups;
        foreach ($groups as $group) {
            $socket->join((string)$group->id);
            $socket->to($group->id)->emit('group_online', $this->sucMsg(['content' => $user->username . '上线了', 'id' => $group->id], '群员上线'));
        }

        $socket->emit('login', $this->sucMsg($data, '登录成功！'));
    }

    /**
     * 收到聊天消息
     * @Event("chatMessage")
     * @param Socket $socket
     * @param $data
     */
    public function onChatMessage(Socket $socket, $data)
    {
        if ($data['send_id'] != UidBand::getInstance()->getUidByFd($socket->getSid())) {
            $socket->emit('chatMessage', $this->errMsg('消息发送:请勿伪造发送者id'));
            return;
        }

        $messageLog = MessageLog::create([
            'send_id' => $data['send_id'],
            'to_id' => $data['to_id'],
            'content' => $data['content'],
            'type' => $data['type'],
        ]);

        $user = User::query()->find($messageLog->send_id);
        $result['username'] = $user->username;
        $result['avatar'] = $user->avatar;
        $result['type'] = $data['type'];
        $result['content'] = $data['content'];
        $result['cid'] = $messageLog->id;
        $result['mine'] = false;
        $result['fromid'] = $data['send_id'];
        $result['timestamp'] = time() * 1000;

        if ($data['type'] == 'friend') {
            $result['id'] = $data['send_id'];
            $socket->to(UidBand::getInstance()->getFdByUid($data['to_id']))->emit('chatMessage', $this->sucMsg($result));
        } elseif ($data['type'] == 'group') {
            $result['id'] = $data['to_id'];
            $socket->to($data['to_id'])->emit('chatMessage', $this->sucMsg($result));
        }


    }
}
